#include <stdio.h>
#include <assert.h>
#include "vertice.h"
#include "vecinos.h"
#include "arista.h"

/**
  \struct Estructura "node" o vertice.
  name : entero que representa el nombre del vertice.
  visited : booleano que indica si el vertice fue marcado/tildado/"etiqueteado".
  list_of_neighbours : enumera y lista los vecinos del vertice.
  neighbours_count : responde a la pregunta.. cuantos vecinos tiene el vertice?
 */
struct s_node{
	int name; /*!< Nombre del nodo*/
	bool visited; /*!< Indica si el nodo fue visitado */
	neighbours list_of_neighbours; /*!< Lista de vecinos del nodo*/
	int neighbours_count; /*!< Cantidad de vecinos del nodo*/
};

/**
  Creador de aristas.
  @param name_passed : entero que representa el nombre del vertice.
  @return : se retorna el nodo creado con su estrucutra
 */
node node_create(int name_passed){
	node nd = NULL;
	nd = (node) malloc(sizeof(struct s_node));
	if (nd == NULL){
        printf("Memoria insuficiente\n");
        exit(1);
	}
    nd->name = name_passed;
	nd->visited = false;
	nd->list_of_neighbours = neighbours_create();
	nd->neighbours_count = 0;
	return nd;
}

/**
  Get Visitado .
    \pre
    <code> (nd != NULL) </code>
  \param nd : tomamos un vertice y averiguamos si fue o no visitado anteriormente.
  \return  : booleano indicando si fue o no visitado.
 */
bool node_visited(node nd){
	assert(nd != NULL);
	return nd->visited;
}


/**
  Get Vecinos .
    \pre
    <code> (nd != NULL) </code>
  \param nd : tomamos un vertice.
  \return  : estructura "neighbours" que representa los vecinos de dicho vertice.
 */
neighbours node_neighbours(node nd){
	assert(nd != NULL);
	return nd->list_of_neighbours;
}


/**
  Destructor de vertice .
   \pre
    <code> (nd != NULL) </code>
  \param nd : tomamos un vertice y liberamos su estructura.
  \return  : puntero a NULL.
 */
node node_destroy(node nd){
	neighbours_destroy(nd->list_of_neighbours);
	free(nd);
	nd = NULL;
	return nd;
}

/**
  Set Visitado .
   \pre
    <code> (nd != NULL) </code>
  \param nd : tomamos un vertice marcamos el campo visited como verdadero.
 */
void node_visit(node nd){
	assert(nd != NULL);
	nd->visited = true;
}


/**
  Get Name.
   \pre
    <code> (nd != NULL) </code>
  \param nd : tomamos un vertice nd.
  \return : devolvemos el nombre solicitado
 */
int node_name (node nd){
	assert(nd != NULL);
	return nd->name;
}


/**
  Set Visitado .
  \pre
    <code> (nd != NULL) </code>
  \param nd : vertice nd.
  \param t : entero que representa el vertice "to" (o vecino)
  \param c : capacidad de la arista a agregar.
  Formamos una nueva arista entre el nodo "nd" y el "t" con capacidad "c". Adjuntamos la misma a la lista de vecinos de "nd".
 */
void node_add_neighbour(node nd, int to, int c){
	edge e;
    assert(nd != NULL);
    e = edge_create(nd->name,to,c);
	if(e != NULL){
		neighbour_add(nd->list_of_neighbours,e);
	}
}
